package com.gxar.file.server.db.service.strategy;

import com.gxar.common.exception.BusinessException;
import com.gxar.file.server.base.common.enums.TargetChannelEnum;
import com.gxar.file.server.base.common.enums.ProductEnum;
import com.gxar.file.server.base.model.ResultCodeEnum;
import com.gxar.file.server.base.model.upload.request.FilePartUploadRequest;
import com.gxar.file.server.base.model.upload.response.FilePartUploadResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author linsy
 * @version 1.0
 * @created 2023/7/12 21:02
 */
@Service
public class TargetChannelStrategyContext {
    private final Map<String, TargetChannelStrategy> STRATEGY_MAP = new ConcurrentHashMap<>();

    public TargetChannelStrategyContext(List<TargetChannelStrategy> channelSourceStrategyList) {
        channelSourceStrategyList.forEach(channelSourceStrategy -> STRATEGY_MAP.put(channelSourceStrategy.getTargetChannel(), channelSourceStrategy));
    }

    /**
     * 上传文件
     *
     * @param channelSourceEnum 上传渠道
     */
    public Boolean uploadFile(TargetChannelEnum channelSourceEnum, ProductEnum productEnum, String fileName, InputStream streamFile, Boolean publicRead) {
        TargetChannelStrategy channelSourceStrategy = Optional.ofNullable(STRATEGY_MAP.get(channelSourceEnum.getName()))
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.TEMPORARILY_UNAVAILABLE));
        return channelSourceStrategy.uploadFile(productEnum, fileName, streamFile, publicRead);
    }

    /**
     * 下载文件
     *
     * @param targetChannelEnum 渠道源
     * @param productEnum       产品
     * @param fileKey           文件key
     * @param response          响应
     * @return 错误信息
     */
    public String downloadFile(TargetChannelEnum targetChannelEnum, ProductEnum productEnum, String fileKey, HttpServletResponse response) {
        TargetChannelStrategy channelSourceStrategy = Optional.ofNullable(STRATEGY_MAP.get(targetChannelEnum.getName()))
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.TEMPORARILY_UNAVAILABLE));
        return channelSourceStrategy.downloadFile(productEnum, fileKey, response);
    }

    /**
     * 获取文件地址
     *
     * @param targetChannelEnum 目标渠道
     * @param product           产品
     * @param name              文件名
     * @return 文件地址
     */
    public String getFileUrl(TargetChannelEnum targetChannelEnum, ProductEnum product, String name) {
        TargetChannelStrategy channelSourceStrategy = Optional.ofNullable(STRATEGY_MAP.get(targetChannelEnum.getName()))
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.TEMPORARILY_UNAVAILABLE));
        return channelSourceStrategy.getFileUrl(product, name);
    }

    /**
     * 分片上传文件
     *
     * @param targetChannelEnum 目标渠道
     * @param product           产品
     * @param name              文件名
     * @param request           请求
     * @param file              文件
     * @return 分片上传文件结果
     */
    public FilePartUploadResponse uploadPartFile(TargetChannelEnum targetChannelEnum, ProductEnum product, String name, FilePartUploadRequest request, MultipartFile file) {
        TargetChannelStrategy channelSourceStrategy = Optional.ofNullable(STRATEGY_MAP.get(targetChannelEnum.getName()))
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.TEMPORARILY_UNAVAILABLE));
        return channelSourceStrategy.uploadPartFile(product, name, request, file);
    }

    /**
     * 删除文件
     *
     * @param productName 产品名称
     * @param fileName    文件名称
     */
    public void deleteFile(TargetChannelEnum targetChannelEnum, String productName, String fileName) {
        TargetChannelStrategy channelSourceStrategy = Optional.ofNullable(STRATEGY_MAP.get(targetChannelEnum.getName()))
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.TEMPORARILY_UNAVAILABLE));
        channelSourceStrategy.deleteFile(productName, fileName);
    }
}
